package com.halachawiki.client;

import java.util.Comparator;
import java.util.List;

import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ScrollEvent;
import com.google.gwt.user.client.Window.ScrollHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratedPopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.ProvidesKey;
import com.halachawiki.client.AuthorService.Status;
import com.halachawiki.shared.PublicAuthor;


public class Authors extends VerticalPanel {
	private AuthorServiceAsync authorService = GWT.create(AuthorService.class);
	private AuthorConstants Constants = GWT.create(AuthorConstants.class);
	//private AuthorMessages Messages = GWT.create(Authors.class);

	List<PublicAuthor> authors;
	
	public Authors() {
		refresh();
	}

	private void refresh() {
		authorService.getAuthors(new AsyncCallback<List<PublicAuthor>>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(List<PublicAuthor> result) {
				authors = result;
				draw();
			} 
		});
	}
	
	private void draw() {
		clear();
		Button newAuthor = new Button(Constants.newAuthorButton());
		add(newAuthor);
		
		final CellTable<PublicAuthor> cellTable = new CellTable<PublicAuthor>(10,
				new ProvidesKey<PublicAuthor>() {
					@Override
					public Object getKey(PublicAuthor item) {
						return item.versionID;
					} 
				});
		add(cellTable);
	    cellTable.setWidth("100%", true); // TODO: Move to CSS
	    cellTable.setTableLayoutFixed(false);
	    
		// Create a data provider.
	    ListDataProvider<PublicAuthor> dataProvider = new ListDataProvider<PublicAuthor>();

	    // Connect the table to the data provider.
	    dataProvider.addDataDisplay(cellTable);

	    // Add the data to the data provider, which automatically pushes it to the
	    // widget.
	    List<PublicAuthor> list = dataProvider.getList();
	    for (PublicAuthor author : authors) {
	      list.add(author);
	    }
	    
	    // add sort handler, connected to data provider.
	    ListHandler<PublicAuthor> sortHandler = new ListHandler<PublicAuthor>(list);
	    cellTable.addColumnSortHandler(sortHandler);

	    // Create a Pager to control the table.
	    SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
	    SimplePager pager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);
	    pager.setDisplay(cellTable);
	    add(pager);

	    // add name column
	    Column<PublicAuthor, String> nameColumn = new Column<PublicAuthor, String>(new TextCell()) {
			@Override
			public String getValue(PublicAuthor object) {
				return object.name;
			} 
		};
		nameColumn.setSortable(true);
		sortHandler.setComparator(nameColumn, new Comparator<PublicAuthor>() {
			@Override
			public int compare(PublicAuthor arg0, PublicAuthor arg1) {
				if (arg0.name==null) { return -1; }
				if (arg1.name==null) { return +1; }
				return arg0.name.compareTo(arg1.name);
			}
		});
		cellTable.addColumn(nameColumn, Constants.nameColumnHeader());

	    // add nickname column
	    Column<PublicAuthor, String> nicknameColumn = new Column<PublicAuthor, String>(new TextCell()) {
			@Override
			public String getValue(PublicAuthor object) {
				return object.getPresentableNicknames();
			} 
		};
		nicknameColumn.setSortable(true);
		sortHandler.setComparator(nicknameColumn, new Comparator<PublicAuthor>() {
			@Override
			public int compare(PublicAuthor arg0, PublicAuthor arg1) {
				return arg0.getPresentableNicknames().compareTo(arg1.getPresentableNicknames());
			}
		});
		cellTable.addColumn(nicknameColumn, Constants.nicknameColumnHeader());
		cellTable.setColumnWidth(nicknameColumn, "100 px");

	    // add period column
	    Column<PublicAuthor, String> periodColumn = new Column<PublicAuthor, String>(new TextCell()) {
			@Override
			public String getValue(PublicAuthor object) {
				if (object.period == null) { return ""; }
				return object.period.getDisplayString();
			} 
		};
		periodColumn.setSortable(true);
		sortHandler.setComparator(periodColumn, new Comparator<PublicAuthor>() {
			@Override
			public int compare(PublicAuthor arg0, PublicAuthor arg1) {
				int ord0 = -1;
				int ord1 = -1;
				if (arg0.period != null)
					ord0 = arg0.period.getIndex();
				if (arg1.period != null)
					ord1 = arg1.period.getIndex();
				return ord0 - ord1;
			}
		});
		cellTable.addColumn(periodColumn, Constants.periodColumnHeader());
		cellTable.setColumnWidth(periodColumn, "100 px");

		// Add edit column.
		ActionCell<PublicAuthor> ac = new ActionCell<PublicAuthor>(Constants.editButton(),
				new ActionCell.Delegate<PublicAuthor>() {
			public void execute(PublicAuthor author) {
				showAuthorEditor(author);
			}
		});
		Column<PublicAuthor, PublicAuthor> buttonColumn = new Column<PublicAuthor, PublicAuthor>(ac) {
			@Override
			public PublicAuthor getValue(PublicAuthor object) {
				return object;
			} 
		};
		cellTable.addColumn(buttonColumn,"");
		
		newAuthor.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				showAuthorEditor(null);
			}
		});

	}
	private void showAuthorEditor(PublicAuthor author) {
		final DecoratedPopupPanel simplePopup = new DecoratedPopupPanel(false);
		simplePopup.setGlassEnabled(true);
		simplePopup.center();
		final HandlerRegistration scrollListener = Window.addWindowScrollHandler(new ScrollHandler() {
			@Override
			public void onWindowScroll(ScrollEvent event) {
				simplePopup.setGlassEnabled(false);
				simplePopup.setGlassEnabled(true);
				simplePopup.center();
			} 
		});
		AuthorEditor newAuthor = new AuthorEditor(author, new AsyncCallback<PublicAuthor>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Internal error " + caught);
			}
			@Override
			public void onSuccess(PublicAuthor author) {
				if (author == null) { // user cancelled
					simplePopup.hide();
					scrollListener.removeHandler();
					return;
				}
				authorService.newAuthor(author, new AsyncCallback<Status>() {
					@Override
					public void onFailure(Throwable caught) {
						Window.alert("AJAX Failure " + caught);
						simplePopup.hide();
						scrollListener.removeHandler();
					}
					@Override
					public void onSuccess(Status result) {
						if (result != Status.OK)
							Window.alert("newAuthor result " + result);
						simplePopup.hide();
						scrollListener.removeHandler();
						refresh();								
					}
				});
			}
		});
		simplePopup.setWidget(newAuthor);
		simplePopup.show();
		simplePopup.center();
	}
}
